package com.wzcl.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.wzcl.app.dao.model.Activity;
import com.wzcl.app.dao.model.CoursePoint;
import com.wzcl.app.dao.repository.CoursePointRepository;
import com.wzcl.app.model.common.BusinessException;
import com.wzcl.app.model.common.CodeMsg;
import com.wzcl.app.model.common.MyPage;
import com.wzcl.app.model.dto.CoursePointDto;
import com.wzcl.app.service.CoursePointService;
import com.wzcl.app.service.CourseService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Log4j2
@Service
public class CoursePointServiceImpl implements CoursePointService {

    @Autowired
    private CoursePointRepository repository;

    @Autowired
    private CourseService courseService;

    @Override
    public CoursePoint addCoursePoint(CoursePointDto coursePointDto) {
        //校验课程
        courseService.getAndCheckById(coursePointDto.getCourseId());
        //新增
        CoursePoint coursePoint = new CoursePoint();
        BeanUtils.copyProperties(coursePointDto, coursePoint);
        return repository.save(coursePoint);
    }

    @Override
    public CoursePoint delCoursePointById(Integer id) {
        //校验获取
        CoursePoint coursePoint = getAndCheckById(id);
        //删除
        log.info("CoursePoint:{} Physical deletion", JSON.toJSONString(coursePoint));
        repository.delete(coursePoint);
        return coursePoint;
    }

    @Override
    public CoursePoint updateCoursePoint(CoursePointDto coursePointDto) {
        //校验获取
        CoursePoint coursePoint = getAndCheckById(coursePointDto);
        //修改
        BeanUtils.copyProperties(coursePointDto, coursePoint, "id", "courseId", "orderNo");
        return repository.save(coursePoint);
    }

    @Override
    public CoursePoint getCoursePointById(Integer id) {
        return repository.findById(id).orElse(null);
    }


    @Override
    public CoursePoint getAndCheckById(Integer id) {
        if (id == null) {
            throw new BusinessException(CodeMsg.MUST_BE_NOT_NULL, "缺少课程大纲Id");
        }
        CoursePoint coursePoint = getCoursePointById(id);
        if (coursePoint == null) {
            throw new BusinessException(CodeMsg.COURSE_POINT_NOT_EXIST);
        }
        return coursePoint;
    }

    @Override
    public List<CoursePoint> getCoursePointList(CoursePointDto coursePointDto) {
        return repository.findAll(getSpecification(coursePointDto), coursePointDto.getSort());
    }

    @Override
    public MyPage<CoursePoint> getCoursePointPage(CoursePointDto coursePointDto) {
        Page<CoursePoint> all = repository.findAll(getSpecification(coursePointDto), coursePointDto.getPageable());
        ArrayList<CoursePoint> list = new ArrayList<>(all.getContent());
        MyPage<CoursePoint> myPage = new MyPage<>();
        myPage.setContent(list);
        myPage.setTotalElements(all.getTotalElements());
        return myPage;
    }


    private Specification<CoursePoint> getSpecification(CoursePointDto coursePointDto) {
        return new Specification<CoursePoint>() {
            @Override
            public Predicate toPredicate(Root<CoursePoint> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (coursePointDto.getCourseId() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("courseId"), coursePointDto.getCourseId()));
                }
                if (StringUtils.isNotBlank(coursePointDto.getName())) {
                    predicates.add(criteriaBuilder.like(root.get("name"), "%" + coursePointDto.getName() + "%"));
                }
                if (StringUtils.isNotBlank(coursePointDto.getTeacherName())) {
                    predicates.add(criteriaBuilder.like(root.get("teacherName"), "%" + coursePointDto.getTeacherName() + "%"));
                }
                String date = coursePointDto.getDate();
                if (StringUtils.isNotBlank(date)) {
                    predicates.add(criteriaBuilder.like(root.get("date"),date + "%"));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }

}
